﻿
Imports std

Public Module windows

    Private users() As vector(Of USER_INFO) = Nothing
    Private dirty As Boolean = False

    Public Function listusers(ByVal level As Int32) As vector(Of USER_INFO)
        Select Case level
            Case 1
                Return listusers(Of USER_INFO_1)(level)
            Case Else
                Return listusers(Of USER_INFO_1)(level)
        End Select
    End Function

    Public Function listusers(Of T As USER_INFO)(Optional ByVal level As Int32 = 1) As vector(Of USER_INFO)
        If users Is Nothing OrElse users.Length <= level OrElse dirty Then
            If users Is Nothing Then
                ReDim users(level + 1)
            ElseIf users.Length <= level Then
                ReDim Preserve users(level + 1)
            End If

            Dim entriesRead As Int32
            Dim totalEntries As Int32
            Dim _resume As Int32
            Dim ptr As IntPtr
            If NetUserEnum(Nothing, level, 0, ptr, -1, entriesRead, totalEntries, _resume) = 0 _
                AndAlso entriesRead > 0 Then
                users(level) = New vector(Of USER_INFO)
                Dim iter As IntPtr = ptr
                Dim i As Int32
                For i = 0 To entriesRead - 1
                    Dim user As T
                    user = convertor.cast(Of T)(System.Runtime.InteropServices.Marshal.PtrToStructure(iter, GetType(T)))
                    users(level).push_back(user)
                    iter = convertor.cast(Of IntPtr)(convertor.cast(Of Int32)(iter, True) + sizeof(Of T)())
                Next
                NetApiBufferFree(ptr)
            End If
        End If

        Return users(level)
    End Function

    Public Function islocaluser(ByVal username As String, ByVal password As String) As Boolean
        Dim users As vector(Of USER_INFO) = Nothing
        users = listusers(1)
        Dim i As Int64
        For i = 0 To users.size() - 1
            Dim user As USER_INFO_1
            user = convertor.cast(Of USER_INFO_1)(users(i))
            If strsame(user.name, username, False) AndAlso strsame(user.pwd, password, True) Then
                Return True
            End If
        Next

        Return False
    End Function

    Public Sub listusersUnittest()
        Dim users As vector(Of USER_INFO) = Nothing
        users = listusers(1)
        Dim i As Int64
        For i = 0 To users.size() - 1
            Console.WriteLine(convertor.cast(Of USER_INFO_1)(users(i)).name)
        Next
    End Sub
End Module
